package org.msfj.toilets.util;

import java.util.Arrays;

public class ByteUtil {
    /**
     * 将 byte 数组转化为十六进制字符串
     *
     * @param bytes byte[] 数组
     * @param begin 起始位置
     * @param end   结束位置
     * @return byte 数组的十六进制字符串表示
     */
    public static String bytesToHex(byte[] bytes, int begin, int end) {
        StringBuilder hexBuilder = new StringBuilder(2 * (end - begin));
        for (int i = begin; i < end; i++) {
            hexBuilder.append(Character.forDigit((bytes[i] & 0xF0) >> 4, 16)); // 转化高四位
            hexBuilder.append(Character.forDigit((bytes[i] & 0x0F), 16)); // 转化低四位
            hexBuilder.append(' '); // 加一个空格将每个字节分隔开
        }
        return hexBuilder.toString().toUpperCase();
    }

    //将低字节在前转为int，高字节在后的byte数组(与IntToByteArray1想对应)
    public static int bytesToInt(byte[] bArr) {
        if (bArr.length != 4) {
            return -1;
        }
        return (int) ((((bArr[3] & 0xff) << 24)
                | ((bArr[2] & 0xff) << 16)
                | ((bArr[1] & 0xff) << 8)
                | ((bArr[0] & 0xff) << 0)));
    }

    /**
     * 16进制转换成为string类型字符串
     *
     * @param s
     * @return
     */
    public static String hexStringToString(String s) {
        if (s == null || s.equals("")) {
            return null;
        }
        s = s.replace(" ", "");
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            s = new String(baKeyword, "UTF-8");
            new String();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return s;
    }

    /**
     * 16进制转换成为string类型字符串
     *
     * @param s
     * @return
     */
    public static int hexStringToInt(String s) {
        int result = -1;
        if (s == null || s.equals("")) {
            return result;
        }
        s = s.replace(" ", "");
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        result = bytesToInt(baKeyword);
        return result;
    }

    /**
     * FE 5C 4B 89 27 00 00 00 65 00 00 00 00 14 00 00 00 03 00 FF FF 05 32 31 2E 31 30 04 00 FF FF 05 32 35 2E 33 37 FF FF
     * FE 5C 4B 89 20 00 00 00 65 00 00 00 00 0D 00 00 00 06 FF FF FF 08 00 00 00 00 00 00 00 00 FF FF
     * FE 5C 4B 89 20 00 00 00 65 00 00 00 00 0D 00 00 00 06 FF FF FF 08 00 22 00 13 00 00 00 00 FF FF
     * 前四位为固定标头
     * 第五位到第八位为包括标头标尾在内的所有字节长度
     * 第九位为消息类型
     * （61为客户端请求连接到服务器，服务器没响应的话会一直发送；
     * 62为服务器发送给客户端的认证反馈；
     * 65为服务器查询或者客户端回传检测信息
     * 91为客户端定时给服务器发送的心跳信息；）
     * 第十位到第十三位为客户端id
     * 第十四位到第十七位为具体指令长度
     * 第十八位到末尾第三位为具体指令内容
     * 末尾两位为固定标尾
     */


    public static int getTotalSize(byte[] bytes) {
        String hex = ByteUtil.bytesToHex(bytes, 4, 8);
        return ByteUtil.hexStringToInt(hex);
    }

    public static String getMessageType(byte[] bytes) {
        return ByteUtil.bytesToHex(bytes, 8, 9);
    }

    public static int getId(byte[] bytes) {
        String hex = ByteUtil.bytesToHex(bytes, 9, 13);
        return ByteUtil.hexStringToInt(hex);
    }

    public static int getOrderSize(byte[] bytes) {
        String hex = ByteUtil.bytesToHex(bytes, 13, 17);
        return ByteUtil.hexStringToInt(hex);
    }

    public static String getTemperature(byte[] bytes) {
        String hex = ByteUtil.bytesToHex(bytes, 22, 27);
        return ByteUtil.hexStringToString(hex);
    }

    public static String getHumidity(byte[] bytes) {
        String hex = ByteUtil.bytesToHex(bytes, 32, 37);
        return ByteUtil.hexStringToString(hex);
    }

    public static byte[] getIoInfo(byte[] bytes, int start, int end) {
        byte[] info = new byte[16];
        int j = 0;
        for (int i = 0; i < getBooleanArray(bytes[start]).length; i++) {
            info[j] = getBooleanArray(bytes[start])[i];
            j++;
        }
        j = 8;
        for (int i = 0; i < getBooleanArray(bytes[end]).length; i++) {
            info[j] = getBooleanArray(bytes[end])[i];
            j++;
        }
        byte[] result = new byte[16];
        j = 0;
        for (int i = info.length - 1; i >= 0; i--) {
            result[j] = info[i];
            j++;
        }
        return result;
    }

    public static void main(String[] args) throws Exception {
        byte[] infrared = {
                (byte) 0xfe, (byte) 0x5c, (byte) 0x4b, (byte) 0x89,
                (byte) 0x20, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                (byte) 0x65,
                (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                (byte) 0x0d, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                (byte) 0x06, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
                (byte) 0xff, (byte) 0xff};
//        System.out.println(Arrays.toString(getIoInfo(infrared,22,23)));
        System.out.println(Arrays.toString(getIoInfo(infrared, 24, 25)));
//        System.out.println(Arrays.toString(getIoInfo(infrared,26,27)));
//        System.out.println(Arrays.toString(getIoInfo(infrared,28,29)));

//        byte infrared = 0x04;
//        String tString = Integer.toBinaryString((infrared & 0xFF) - 0x100).substring(1);
//        System.out.println(tString);
//        String hex = "400";
//        Integer a = Integer.parseInt(hex,16);
//        System.out.println(a);
//        byte[] b = new byte[16];
//        b[15] = (byte) (a >> 120 & 0xff);
//        b[14] = (byte) (a >> 112 & 0xff);
//        b[13] = (byte) (a >> 104 & 0xff);
//        b[12] = (byte) (a >> 96 & 0xff);
//        b[11] = (byte) (a >> 88 & 0xff);
//        b[10] = (byte) (a >> 80 & 0xff);
//        b[9] = (byte) ((a >> 72) & 0xff);
//        b[8] = (byte) ((a >> 64) & 0xff);
//        b[7] = (byte) (a >> 56 & 0xff);
//        b[6] = (byte) (a >> 48 & 0xff);
//        b[5] = (byte) (a >> 40 & 0xff);
//        b[4] = (byte) (a >> 32 & 0xff);
//        b[3] = (byte) (a >> 24 & 0xff);
//        b[2] = (byte) ((a >> 16) & 0xff);
//        b[1] = (byte) ((a >> 8) & 0xff);
//        b[0] = (byte) (a & 0xff);
//
//        for (int i = b.length-1; i>=0; i--){
//            System.out.print(byteToBit(b[i]) + "\n");
//        }
//
//        String binaryStr = java.lang.Integer.toBinaryString(a);
//        System.out.println("the result is : " + binaryStr);
//
//
//        byte aa = 0x04; // 0011 0101
//        byte bb = 0x40; // 0011 0101
        // 输出 [0, 0, 1, 1, 0, 1, 0, 1]
//        System.out.println(Arrays.toString(getBooleanArray(aa)) + Arrays.toString(getBooleanArray(bb)));
    }

    /**
     * 把byte转为字符串的bit
     */
    public static String byteToBit(byte b) {
        return ""
                + (byte) ((b >> 7) & 0x1) + (byte) ((b >> 6) & 0x1)
                + (byte) ((b >> 5) & 0x1) + (byte) ((b >> 4) & 0x1)
                + (byte) ((b >> 3) & 0x1) + (byte) ((b >> 2) & 0x1)
                + (byte) ((b >> 1) & 0x1) + (byte) ((b >> 0) & 0x1);
    }

    /**
     * 将byte转换为一个长度为8的byte数组，数组每个值代表bit
     */
    public static byte[] getBooleanArray(byte b) {
        byte[] array = new byte[8];
        for (int i = 7; i >= 0; i--) {
            array[i] = (byte) (b & 1);
            b = (byte) (b >> 1);
        }
        return array;
    }

}
